﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using Boardgame;
using BoardgameModel;
using BoardgameModelViewed;
using AppInfo;
using WinGameControls;


namespace WinChessController
{
    public interface IChessViewFactory
    {
        void Make (ChessController controller, ChessModelBase modelbase);
    }


    public partial class ChessController : Form
    {
        private ChessModel model;
        private IChessViewFactory viewFactory;

        public ChessController (IChessViewFactory viewFactory)
        {
            this.viewFactory = viewFactory;
            InitializeComponent();

            checkerboard.LeftClick += Checkerboard_LeftClick;
            checkerboard.RightDown += Checkerboard_RightDown;
            checkerboard.RightUp += Checkerboard_RightUp;
        }


        // On entry, controller has been created.
        private void ChessController_Shown (object sender, EventArgs args)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Text = AppAbout.Product (assembly) + " " + AppAbout.Version (assembly);

            // Create the model.
            model = new ChessModel (checkerboard.Dimensions.X, checkerboard.Dimensions.Y);

            // Create the view and connect it to the controller and model.
            viewFactory.Make (this, model);
        }


        private void Checkerboard_LeftClick (object sender, EventArgs args)
        {
            WinCheckerboardClickArgs cArgs = (WinCheckerboardClickArgs) args;

            if (! checkerboard.Selection.HasValue)
            {
                if (model.IsMovable (cArgs.X, cArgs.Y))
                    checkerboard.SetSelection (cArgs.X, cArgs.Y);
            }
            else
                if (checkerboard.Selection.Value.X == cArgs.X
                    && checkerboard.Selection.Value.Y == cArgs.Y)
                {
                    Debug.WriteLine ("SAME");
                    checkerboard.ClearSelection();
                }
                else
                {
                    try
                    {
                        model.MakeMove (checkerboard.Selection.Value.X, checkerboard.Selection.Value.Y,
                                        cArgs.X, cArgs.Y);
                    }
                    catch (InvalidOperationException ex)
                    {
                        WinMessageBox.Show (Icon, ex.Message, "SORRY");
                    }
                }
        }


        private void Checkerboard_RightDown (object sender, EventArgs args)
        {
            WinCheckerboardClickArgs cArgs = (WinCheckerboardClickArgs) args;
            model.BeginShowMoves (cArgs.X, cArgs.Y);
        }


        private void Checkerboard_RightUp (object sender, EventArgs args)
        {
            model.EndShowMoves();
        }

        //// //// //// //// //// //// //// //// 

        private void ChessController_ResizeEnd (object sender, EventArgs args)
        {
            Invalidate();
        }

        //// //// //// //// //// //// //// //// 

        private void fileMenuExit_Click (object sender, EventArgs args)
        {
            Application.Exit();
        }

        //// //// //// //// //// //// //// //// 

        private void gameMenuUndo_Click (object sender, EventArgs args)
        {
            try
            {
                model.UndoMove();
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show (ex.Message, "UNEXPECTED ERROR");
            }
        }


        private void gameMenuNew_Click (object sender, EventArgs args)
        {
            model.Setup();
        }


        private void gameMenuResign_Click (object sender, EventArgs args)
        {
            model.ResignGame();
        }

        //// //// //// //// //// //// //// //// 

        private void drawMenuRequestDraw_Click (object sender, EventArgs args)
        {
            model.RequestDraw();
        }


        private void drawMenuThreefoldNow_Click (object sender, EventArgs args)
        {
            try
            {
                model.RequestThreefoldRepetitionDrawNow();
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show (ex.Message, "UNEXPECTED ERROR");
            }
        }

        private void drawMenuThreefoldLater_Click (object sender, EventArgs args)
        {
            try
            {
                model.IsThreefoldRepDrawOnMoveRequested = ! model.IsThreefoldRepDrawOnMoveRequested;
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show (ex.Message, "UNEXPECTED ERROR");
            }
        }


        private void drawMenuFiftyMove_Click (object sender, EventArgs args)
        {
            try
            {
                model.RequestFiftyMovesRuleDraw();
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show (ex.Message, "UNEXPECTED ERROR");
            }
        }

        //// //// //// //// //// //// //// //// 

        private void helpMenuAbout_Click (object sender, EventArgs args)
        {
            using (var dialog = new WinAbout())
            {
                dialog.ShowDialog();
            }
        }

        //// //// //// //// //// //// //// //// 

        private void promoList_SelectionChangeCommitted (object sender, EventArgs args)
        {
            model.SetPromotion (promoList.Text);
        }
    }
}
